/*
    看代码之前的备注：
    1、不要问为啥编辑和查看编辑详情的时候数据格式为什么不一样，同一个字段为什么一个叫codelist,一个叫list
    2、不要问为啥第三步的数据源是来源于第二步，同时第二步还要给个默认赋值，导致第三步校验会被触发
    3、不要问为什么这块业务逻辑为什么绕，看你就知道了
    ...
 */

import React, { useState, useEffect } from 'react';
import { Tabs, Button, Popover, Form, Spin, message } from 'antd';
import { BottomAction } from '@/components';
import IconFont from '@/components/IconFont';
import { size } from 'lodash';
import { withRouter, router } from 'umi';
import { useRequest, defaultFormatResult } from '@/hooks';
import { hasWorkFlowByType } from '@/pages/WorkFlow/utils';
import CancelEditConfirm from '@/components/CancelEditConfirm';
import ButtonConfirm from '@/pages/Setting/Privilege/components/ButtonConfirm';
import styles from './index.less';
import { BasicSetting, DataPermission, FunctionPermission, AuthorizedPost } from './components';
import {
    getPrivilegeTemplateEditInfo,
    saveRoleInDraftMode,
    saveRoleInSubmitMode,
    getPrivilegeResources
} from '../../services';

const { TabPane } = Tabs;

// 权限管理-新增/编辑模板
const Edit = ({ form, location }) => {
    const [activeKey, setActiveKey] = useState('1');
    const [workFlowLoading, setWorkFlowLoading] = useState(false);
    const { query } = location;

    const { validateFields, getFieldsError, setFieldsValue, getFieldsValue, validateFieldsAndScroll } = form;
    const { code, actionType } = query;
    const [isEdit, setIsEdit] = useState();
    const [isCopy, setIsCopy] = useState();

    useEffect(() => {
        setIsEdit(code !== undefined);
    }, [code]);

    useEffect(() => {
        setIsCopy(actionType && actionType === 'copy');
    }, [actionType]);

    // 获取详情
    const { data: detailData, run: runDetail, loading: detailLoading, mutate } = useRequest(
        () => getPrivilegeTemplateEditInfo(code),
        {
            manual: true,
            ...defaultFormatResult,
            onSuccess: async res => {
                // 复制的时候标题要加上-副本
                if (size(res) > 0) {
                    const {
                        nameZh,
                        nameEn,
                        type,
                        icon,
                        remarkZh,
                        remarkEn,
                        authorityList,
                        dataScopeSetType = 0,
                        authorityDataList,
                        dutyCodeList
                    } = res;
                    await mutate({ ...res, icon: isCopy ? undefined : icon });
                    await setFieldsValue({
                        nameZh: isCopy ? `${nameZh} - 副本` : nameZh,
                        nameEn: isCopy ? `${nameEn} - copy` : nameEn,
                        type,
                        icon: isCopy ? undefined : icon,
                        remarkZh,
                        remarkEn,
                        authorityList,
                        dataScopeSetType,
                        authorityDataList,
                        dutyCodeList
                    });
                }
            }
        }
    );

    useEffect(() => {
        if (isEdit) {
            runDetail();
        }
    }, [isEdit, runDetail]);

    // 保存草稿
    const { run: draftRun, loading: draftLoading } = useRequest(params => saveRoleInDraftMode(params), {
        manual: true,
        defaultFormatResult
    });

    // 提交表单
    const { run: roleSubmitRun, loading: roleSubmitLoading } = useRequest(params => saveRoleInSubmitMode(params), {
        manual: true
    });

    // 租户的功能权限列表,新增状态下第二步的数据源
    const { run: runFuncPermission, loading: funcPermissionLoading } = useRequest(() => getPrivilegeResources(), {
        manual: true,
        onSuccess: res => {
            if (res?.code === 10000) {
                setFieldsValue({ authorityList: res?.data, dataScopeSetType: 0 });
            } else {
                message.error(res?.msg);
            }
        }
    });
    useEffect(() => {
        if (isEdit === false) {
            runFuncPermission();
        }
    }, [isEdit, runFuncPermission]);

    // tab头部重写
    const renderTabBar = (props, DefaultTabBar) => (
        <div className={styles.tabBar}>
            <div className={styles.tabBarName}>编辑模版</div>
            <DefaultTabBar {...props} style={{ flex: 1 }} />
        </div>
    );

    // tab配置
    const formTabPaneArray = [
        {
            name: '基础设置',
            tabValidateFields: ['nameZh', 'type', 'icon', 'remarkZh', 'remarkEn'],
            component: <BasicSetting form={form} detailData={detailData} />
        },
        {
            name: '功能权限',
            tabValidateFields: ['authorityList'],
            component: () => (
                <FunctionPermission form={form} loading={funcPermissionLoading} isShow={activeKey === '2'} />
            )
        },
        {
            name: '数据权限',
            tabValidateFields: ['authorityDataList'],
            component: <DataPermission form={form} />
        },
        {
            name: '授权岗位',
            component: <AuthorizedPost form={form} />
        }
    ];

    // 获取表单错误信息
    const validateErrors = React.useMemo(() => {
        const errors = getFieldsError();
        const arr = [];
        Object.entries(errors).forEach(([key, value]) => {
            if (value !== undefined) {
                const obj = { key, errMsg: value };
                // 在tab数据中找到相对应的位置
                for (let i = 0; i < formTabPaneArray.length; i += 1) {
                    const { tabValidateFields, name } = formTabPaneArray[i];
                    if (tabValidateFields && tabValidateFields?.includes(key)) {
                        obj.tabName = name;
                        obj.tabIndex = String(i + 1);
                        break;
                    }
                }
                arr.push(obj);
            }
        });
        return arr;
    }, [formTabPaneArray, getFieldsError]);

    const handleSubmit = type => {
        const values = getFieldsValue();

        let params = {
            code,
            ...detailData,
            ...values,
            authorityList:
                values &&
                values?.authorityList
                    ?.filter(item => {
                        const { WEB, APP, PC } = item.selectedScope;
                        return !!(WEB || APP || PC);
                    })
                    ?.map(item => ({
                        resourceCode: item.resourceCode,
                        selectedScope: item.selectedScope
                    })) // 过滤选中的功能权限
        };

        // 复制，清除部分参数
        if (isCopy) {
            delete params.code;
            delete params.auditCode;
        }

        // 数据权限dataScopeSetType是全局统一（0）的时候要把authorityDataList权限数组全部改成一致的
        if (params?.dataScopeSetType === 0 && size(params.authorityDataList) > 0) {
            const firstItemData = params.authorityDataList[0] || {};
            const { administrativeScope, companyCodeList, orgCodeList, organizationalScope } = firstItemData;
            params.authorityDataList = params.authorityDataList.map(item => ({
                ...item,
                administrativeScope,
                companyCodeList,
                orgCodeList,
                organizationalScope
            }));
        }

        // 提交的时候在对数据进行转换，这样是编辑提交的时候要处理下!!??
        const authorityDataList = params.authorityDataList?.map(item => {
            let { companyCodeList, orgCodeList } = item;
            companyCodeList = companyCodeList?.map(subItem =>
                typeof subItem === 'string' ? subItem : subItem.companyCode
            );
            orgCodeList = orgCodeList?.map(subItem => (typeof subItem === 'string' ? subItem : subItem.orgCode));
            return { ...item, companyCodeList, orgCodeList };
        });
        params = { ...params, authorityDataList };

        console.log('= ==>params', params);
        if (type === 'draft') {
            validateFieldsAndScroll(['nameZh', 'type'], async err => {
                if (!err) {
                    const res = await draftRun(params);
                    if (res?.code === 10000) {
                        message.success(res?.msg, 3);
                        history.push({
                            pathname: history.pathname,
                            query: { code: res?.data }
                        });
                    } else {
                        message.error(res?.msg);
                    }
                }
            });
        } else {
            // 先保存草稿在提交
            validateFields({ force: true }, async err => {
                if (!err) {
                    // 校验流程是否存在
                    setWorkFlowLoading(true);
                    const { workFlowUrl } = await hasWorkFlowByType('PrivilegeTemplateApply');
                    setWorkFlowLoading(false);
                    if (workFlowUrl) {
                        const res = await draftRun(params);
                        const { data: id, code: resultCode, msg } =
                            (await roleSubmitRun({ ...params, code: res?.data })) || {}; // 因为要先保存草稿，所以提交的全是草稿

                        if (res?.code === 10000) {
                            history.push({
                                pathname: history.pathname,
                                query: { code: res?.data }
                            });
                        }
                        if (resultCode === 10000) {
                            history.push(`${workFlowUrl}${id}`);
                        } else {
                            message.error(msg);
                        }
                    }
                }
            });
        }
    };

    return (
        <div className={styles.templateEditTabsWrap}>
            <Spin spinning={detailLoading || draftLoading || workFlowLoading}>
                <Tabs
                    size="large"
                    activeKey={activeKey}
                    tabBarGutter={64}
                    renderTabBar={renderTabBar}
                    onTabClick={e => {
                        setActiveKey(e);
                    }}
                >
                    {formTabPaneArray.map((item, index) => (
                        <TabPane
                            forceRender
                            tab={
                                <div className={styles.tabBarStep}>
                                    <span className={styles.num}>{index + 1}</span>
                                    {item.name}
                                </div>
                            }
                            key={String(index + 1)}
                        >
                            {index === 1 && item.component()}
                            {index !== 1 && item.component}
                        </TabPane>
                    ))}
                </Tabs>

                <BottomAction>
                    {size(validateErrors) > 0 && (
                        <Popover
                            placement="topLeft"
                            overlayClassName={styles.errorPopoverContent}
                            content={
                                <div>
                                    <p>以下信息未完善，请完善后提交</p>
                                    <ul>
                                        {validateErrors.map(item => {
                                            const { errMsg, tabName, tabIndex, key } = item;
                                            return (
                                                <li key={key}>
                                                    <div>
                                                        <b>{tabName}</b>
                                                        <span>{errMsg}</span>
                                                    </div>
                                                    {activeKey !== tabIndex && (
                                                        <Button
                                                            onClick={() => {
                                                                setActiveKey(tabIndex);
                                                            }}
                                                            type="link"
                                                            style={{ padding: '0' }}
                                                        >
                                                            去完善
                                                        </Button>
                                                    )}
                                                </li>
                                            );
                                        })}
                                    </ul>
                                </div>
                            }
                        >
                            <span className={styles.errorMsg}>
                                <IconFont icon="iconnitificationIcon" />
                                <em>{size(validateErrors)}</em> 条信息未完善
                            </span>
                        </Popover>
                    )}
                    <CancelEditConfirm linkUrl="/setting/privilege/templatemanagement">
                        <Button>取消</Button>
                    </CancelEditConfirm>
                    <ButtonConfirm
                        confirmVisible={() => {
                            if (isEdit && !isCopy) {
                                const { showStatus } = detailData;
                                // 只要是草稿状态就提示
                                if ([-999, -998].find(item => item === showStatus) !== undefined) {
                                    return Promise.resolve(false);
                                }
                                return Promise.resolve(true);
                            }
                            return Promise.resolve(true);
                        }}
                        onConfirm={() => handleSubmit('draft')}
                    >
                        <Button loading={draftLoading} type="primary" ghost>
                            保存
                        </Button>
                    </ButtonConfirm>

                    <Button
                        type="primary"
                        loading={roleSubmitLoading || workFlowLoading}
                        onClick={() => handleSubmit()}
                    >
                        下一步
                    </Button>
                </BottomAction>
            </Spin>
        </div>
    );
};

export default withRouter(Form.create({ name: 'privilegeTemplateEdit' })(Edit));
